package cn.miju.unionpay.handler;

import cn.hutool.core.bean.BeanUtil;
import cn.miju.common.content.CodeMessage;
import cn.miju.common.util.OkHttpUtil;
import cn.miju.common.util.ValidationUtil;
import cn.miju.unionpay.constant.UnionPayConstant;
import cn.miju.unionpay.model.TradeStatusQueryRequest;
import cn.miju.unionpay.model.TradeStatusQueryResponse;
import cn.miju.unionpay.model.UnionPayRequest;
import cn.miju.unionpay.model.UnionPayResponse;
import cn.miju.unionpay.properties.UnionPayProperties;
import cn.miju.unionpay.request.UnionPayQueryOrderReq;
import cn.miju.unionpay.response.UnionPayBaseResp;
import cn.miju.unionpay.response.UnionPayQueryOrderResp;
import cn.miju.unionpay.util.UnionPaySignUtil;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Set;

/**
 * <pre>
 * 订单查询
 * </pre>
 *
 * @author zhuming
 * @version 1.0.0
 * @since 2023-03-15 15:35
 */
@Slf4j
@Component
public class UnionPayQueryOrderHandler extends AbstractUnionPayHandler<UnionPayQueryOrderReq, UnionPayQueryOrderResp> {
    /**
     * 可选返回参数(如果接口所需参数不满足需求，可按照官方接口文档，原样传入对应参数)
     */
    private Set<String> optionalRespParams;
    @Override
    public TradeStatusQueryRequest beforeRequest(UnionPayQueryOrderReq req) {
        ValidationUtil.validate(req);
        UnionPayProperties unionPayProperties = req.getUnionPayProperties();
        UnionPayRequest request = super.beforeRequest(req);
        request.setTxnType(UnionPayConstant.TxnType.QUERY);
        request.setTxnSubType(UnionPayConstant.TxnSubType.DEFAULT);
        request.setBizType(UnionPayConstant.BizType.B2C);
        request.setMerId(unionPayProperties.getMerchantNo());
        TradeStatusQueryRequest tradeStatusQueryRequest = BeanUtil.copyProperties(request, TradeStatusQueryRequest.class);
        tradeStatusQueryRequest.setOrderId(req.getOutTradeNo());
        optionalRespParams = req.getOptionalRespParams();
        super.setOptionalReqParams(tradeStatusQueryRequest, req.getOptionalReqParams());
        return tradeStatusQueryRequest;
    }

    /**
     * 核心执行
     *
     * @param req {@link UnionPayQueryOrderReq}
     * @return {@link UnionPayQueryOrderResp}
     */
    @Override
    public UnionPayQueryOrderResp doPlan(UnionPayQueryOrderReq req) {
        ValidationUtil.validate(req);
        UnionPayProperties unionPayProperties = req.getUnionPayProperties();
        TradeStatusQueryRequest request = this.beforeRequest(req);
        // 签名
        Map<String, String> param = JSONObject.parseObject(JSONObject.toJSONString(request), Map.class);
        UnionPaySignUtil.sign(param, unionPayProperties.getSignCertPath(), unionPayProperties.getSignCertPwd());
        String reqParam = UnionPaySignUtil.createLinkString(param, false, true, StandardCharsets.UTF_8.toString());
        // 请求
        log.info("API--交易状态查询--> Request：{}", reqParam);
        String result = OkHttpUtil.doPost(unionPayProperties.getServiceUrl(), reqParam);
        log.info("API--交易状态查询--> Response：{}", result);
        if (StringUtils.isBlank(result)) {
            return UnionPayQueryOrderResp.builder().code(CodeMessage.FAIL.getCode()).msg("响应数据为空").build();
        }
        TradeStatusQueryResponse response = JSONObject.parseObject(JSONObject.toJSONString(UnionPaySignUtil.readLinkStr(result)), TradeStatusQueryResponse.class);
        return this.afterResponse(response);
    }

    /**
     * 响应参数后置处理
     *
     * @param resp 响应参数
     * @return 结果
     */
    @Override
    public UnionPayQueryOrderResp afterResponse(UnionPayResponse resp) {
        UnionPayBaseResp baseResp = UnionPayBaseResp.preBuilder(CodeMessage.SUCCESS);
        TradeStatusQueryResponse response = (TradeStatusQueryResponse) resp;
        if (response.isSuccess()) {
            baseResp = UnionPayBaseResp.preBuilder(CodeMessage.SUCCESS);
            baseResp.setOptionalRespParams(super.getOptionalRespParams(response, optionalRespParams));
        }
        //交易状态：SUCCESS：交易成功 FAIL：交易失败 NOT_EXIT：交易不存在 CANCEL：交易已取消 REFUND：交易已退款
        String tradeStatus = null;
        switch (response.getRespCode()) {
            case "00":
                tradeStatus = "SUCCESS";
                break;
            case "34":
                tradeStatus = "NOT_EXIT";
                break;
            case "45":
                tradeStatus = "REFUND";
                break;
            case "46":
                tradeStatus = "CANCEL";
                break;
            default:
                tradeStatus = "FAIL";
                break;
        }
        UnionPayQueryOrderResp unionPayQueryOrderResp = BeanUtil.copyProperties(baseResp, UnionPayQueryOrderResp.class);
        unionPayQueryOrderResp.setTradeStatus(tradeStatus);
        unionPayQueryOrderResp.setOutTradeNo(response.getOrderId());
        unionPayQueryOrderResp.setTradeNo(response.getQueryId());
        unionPayQueryOrderResp.setTotalAmount(response.getTxnAmt() == null ? null : Integer.getInteger(response.getTxnAmt()));
        return unionPayQueryOrderResp;
    }
}
